/*
 * @Author: 飞越疯人院 353362604@qq.com
 * @Date: 2022-05-25 11:08:02
 * @LastEditors: 飞越疯人院 353362604@qq.com
 * @LastEditTime: 2022-11-01 16:15:54
 * @FilePath: \reconfiguration-administration\src\Common\Mars3D\DrawElement.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { useState, useEffect } from 'react'
import { Form, Button } from 'antd'
import { useBoolean, useEventEmitter, useRequest } from 'ahooks'
import { ElementStyleData } from './Mars3Config'
import { FormItemModal } from './Form'
import { divList } from './style'

const { mars3d } = window

export const DrawElement = ({ Map, Elements, ElementDetailsEvent }) => {
    const [form] = Form.useForm()
    const [Gra, setGra] = useState({})
    const [Layer, setLayer] = useState({})
    const [DrawState, { setTrue }] = useBoolean(false)
    const [FormData, setFormData] = useState([])
    const [ElementsType, setElementsType] = useState()
    const [ElementStyle, setElementStyle] = useState()
    // 绘制属性

    useEffect(() => {
        const { elementType, styleName, styleData } = Elements
        const { formData, type } = ElementStyleData[elementType]
        const AddFormData = JSON.parse(JSON.stringify(formData))
        setElementsType(elementType)
        setElementStyle(type()[styleName].style)
        const graphicLayer = new mars3d.layer.GraphicLayer({ hasEdit: true })
        Map.addLayer(graphicLayer)
        setGra(graphicLayer)
        // 绘制文字
        if (elementType === 'label') {
            graphicLayer.startDraw({ type: elementType, style: type()[styleName].style }).then(res => {
                setLayer(res)
                const { coordinates, text } = res
                form.setFieldsValue({ position: coordinates[0], tableName: text })
                res.on(
                    [
                        mars3d.EventType.editStart,
                        mars3d.EventType.editMovePoint,
                        mars3d.EventType.editStyle,
                        mars3d.EventType.editRemovePoint,
                    ],
                    ({ graphic }) => {
                        const { coordinates, text } = graphic
                        form.setFieldsValue({ position: coordinates[0], tableName: text })
                    },
                )
                setTrue()
            })
        }
        // div图标点
        if (elementType === 'div') {
            graphicLayer.startDraw({ type: 'div', style: type()[styleName].style }).then(res => {
                setLayer(res)
                res.on('click', () => {})
                const { coordinate } = res
                form.setFieldsValue({ position: coordinate, tableName: '默认文字' })
                res.on(
                    [
                        mars3d.EventType.editStart,
                        mars3d.EventType.editMovePoint,
                        mars3d.EventType.editStyle,
                        mars3d.EventType.editRemovePoint,
                    ],
                    ({ graphic }) => {
                        const { coordinate, name } = graphic
                        console.log(coordinate, name)
                        form.setFieldsValue({ position: coordinate, tableName: name })
                    },
                )
                setTrue()
            })
        }
        // 绘制模型 || 绘制点
        if (elementType === 'model' || elementType === 'point' || elementType === 'billboard') {
            graphicLayer
                .startDraw({
                    type: elementType,
                    drawShow: true,
                    style: type()[styleName].style,
                })
                .then(res => {
                    setLayer(res)
                    const { heading, scale, coordinates, style } = res
                    const { label, url } = style
                    form.setFieldsValue({
                        position: coordinates[0],
                        tableName: label.text,
                        heading,
                        scale,
                        textState: 1,
                        modelUrl: url,
                    })
                    res.on(
                        [
                            mars3d.EventType.editStart,
                            mars3d.EventType.editMovePoint,
                            mars3d.EventType.editStyle,
                            mars3d.EventType.editRemovePoint,
                        ],
                        ({ graphic }) => {
                            const { coordinates, heading, scale } = graphic
                            form.setFieldsValue({ position: coordinates[0], heading, scale })
                        },
                    )
                    setTrue()
                })
        }
        // 绘制线 || 曲线 || 管道 || 墙 || 矩形 || 多边形 || 正多边形
        if (
            elementType === 'polyline' ||
            elementType === 'curve' ||
            elementType === 'polylineVolume' ||
            elementType === 'wall' ||
            elementType === 'rectangle' ||
            elementType === 'polygon' ||
            elementType === 'regular' ||
            elementType === 'circle' ||
            elementType === 'ellipse' ||
            elementType === 'sector' ||
            elementType === 'ellipsoid' ||
            elementType === 'cylinder'
        ) {
            graphicLayer.startDraw({ type: elementType, style: type()[styleName].style }).then(res => {
                setLayer(res)
                const { coordinates, style } = res
                const {
                    label,
                    radius,
                    diffHeight,
                    material,
                    closure,
                    rotationDegree,
                    clampToGround,
                    border,
                    startAngle,
                    endAngle,
                    semiMinorAxis,
                    semiMajorAxis,
                    radii_x,
                    radii_y,
                    radii_z,
                    topRadius,
                    bottomRadius,
                    length,
                } = style
                let modifyData = {
                    position: coordinates,
                    tableName: label.text,
                    textState: 1,
                    closure: closure ? '1' : '0',
                }

                if (elementType === 'polylineVolume') {
                    modifyData.radius = radius
                    delete modifyData.closure
                }
                if (elementType === 'wall') {
                    modifyData.dimensions = diffHeight
                    console.log(material)
                    modifyData.speed = material?._speed
                }

                if (
                    elementType === 'rectangle' ||
                    elementType === 'polygon' ||
                    elementType === 'regular' ||
                    elementType === 'circle' ||
                    elementType === 'ellipse' ||
                    elementType === 'sector'
                ) {
                    if (clampToGround === true && AddFormData.findIndex(v => v.name === 'dimensions') !== -1)
                        AddFormData.splice(
                            AddFormData.findIndex(v => v.name === 'dimensions'),
                            1,
                        )
                    modifyData.rotate = rotationDegree
                    modifyData.dimensions = diffHeight
                }

                if (elementType === 'regular' || elementType === 'circle') {
                    modifyData.slices = border
                    modifyData.radius = radius
                    modifyData.rotate = startAngle
                }

                if (elementType === 'ellipse') {
                    modifyData.semiMinorAxis = semiMinorAxis
                    modifyData.semiMajorAxis = semiMajorAxis
                }

                if (elementType === 'sector') {
                    modifyData.dimensions = diffHeight
                    modifyData.radius = radius
                    modifyData.startAngle = startAngle
                    modifyData.endAngle = endAngle
                }
                if (elementType === 'ellipsoid') {
                    modifyData.radii_x = radii_x
                    modifyData.radii_y = radii_y
                    modifyData.radii_z = radii_z
                }
                if (elementType === 'cylinder') {
                    modifyData.topRadius = topRadius
                    modifyData.bottomRadius = bottomRadius
                    modifyData.length = length
                }

                form.setFieldsValue(modifyData)
                res.on(
                    [
                        mars3d.EventType.editStart,
                        mars3d.EventType.editMovePoint,
                        mars3d.EventType.editStyle,
                        mars3d.EventType.editRemovePoint,
                    ],
                    ({ graphic }) => {
                        const { coordinates, style } = graphic
                        const {
                            diffHeight,
                            radius,
                            semiMinorAxis,
                            semiMajorAxis,
                            startAngle,
                            endAngle,
                            radii_x,
                            radii_y,
                            radii_z,
                            topRadius,
                            bottomRadius,
                            length,
                        } = style
                        let modifyOn = { position: coordinates }
                        if (
                            elementType === 'wall' ||
                            elementType === 'rectangle' ||
                            elementType === 'polygon' ||
                            elementType === 'regular' ||
                            elementType === 'sector'
                        )
                            modifyOn.dimensions = diffHeight

                        if (elementType === 'regular') {
                            modifyOn.radius = radius
                            modifyOn.rotate = startAngle
                        }
                        if (elementType === 'ellipse') {
                            modifyOn.semiMinorAxis = semiMinorAxis
                            modifyOn.semiMajorAxis = semiMajorAxis
                        }
                        if (elementType === 'sector') {
                            modifyData.dimensions = diffHeight
                            modifyOn.radius = radius
                            modifyOn.startAngle = startAngle
                            modifyOn.endAngle = endAngle
                        }
                        if (elementType === 'ellipsoid') {
                            modifyOn.radii_x = radii_x
                            modifyOn.radii_y = radii_y
                            modifyOn.radii_z = radii_z
                        }

                        if (elementType === 'cylinder') {
                            modifyOn.topRadius = topRadius
                            modifyOn.bottomRadius = bottomRadius
                            modifyOn.length = length
                        }

                        form.setFieldsValue(modifyOn)
                    },
                )
                setTrue()
            })
        }
        setFormData(AddFormData)
    }, [Elements, Map, form, setTrue])

    const ModelUrlEvent = useEventEmitter()
    ModelUrlEvent.useSubscription(val => {
        let style = ElementStyle
        style.url = val
        Layer.setOptions({ position: form.getFieldValue('position'), style })
    })

    // 节流change数据
    const { runAsync: setColorWait } = useRequest(async data => new Promise(resolve => resolve(data)), {
        throttleWait: 1000,
        manual: true,
    })
    // 修改颜色
    const ColorEvent = useEventEmitter()
    ColorEvent.useSubscription(val => {
        setColorWait(val).then(res => {
            let { style } = Layer
            if (ElementsType === 'label') style.color = val
            else if (ElementsType === 'div') {
                let { className } = style
                let tableName = form.getFieldValue('tableName')
                let sortId = form.getFieldValue('sortId')
                style.html = divList(tableName, res, sortId)[className].style.html
            } else {
                style.color = val
                style.label.color = val
            }
            Layer.setOptions({ style })
        })
    })

    // 清除图层
    useEffect(() => {
        return () => {
            if (JSON.stringify(Gra) !== '{}') Gra.clear()
        }
    }, [Gra])

    return (
        <div className="formBox">
            {DrawState ? (
                <>
                    <Form
                        className="scenesBase"
                        form={form}
                        layout="vertical"
                        onFinish={e => {
                            e.center = JSON.stringify(e.center)
                            e.position = JSON.stringify(e.position)
                            if (e.semiMinorAxis && e.semiMajorAxis) {
                                e.radius = `${e.semiMinorAxis},${e.semiMajorAxis}`
                                delete e.semiMinorAxis
                                delete e.semiMajorAxis
                            }
                            if (e.startAngle && e.endAngle) {
                                e.angle = JSON.stringify([e.startAngle, e.endAngle])
                                delete e.startAngle
                                delete e.endAngle
                            }
                            if (e.radii_x && e.radii_y && e.radii_z) {
                                e.radius = JSON.stringify([e.radii_x, e.radii_y, e.radii_z])
                                delete e.radii_x
                                delete e.radii_y
                                delete e.radii_z
                            }
                            if (e.topRadius && e.bottomRadius && e.length) {
                                e.radius = JSON.stringify([e.topRadius, e.bottomRadius, e.length])
                                delete e.topRadius
                                delete e.bottomRadius
                                delete e.length
                            }
                            const data = { ...e, elementsUuid: Elements.elementUuid }
                            ElementDetailsEvent.emit({ type: 'add', data: data })
                        }}
                        onValuesChange={({
                            tableName,
                            heading,
                            scale,
                            textState,
                            closure,
                            radius,
                            dimensions,
                            speed,
                            altitude,
                            rotate,
                            slices,
                            semiMinorAxis,
                            semiMajorAxis,
                            topRadius,
                            bottomRadius,
                            length,
                        }) => {
                            // let name = ElementStyle
                            let style = Layer.style
                            if (tableName) {
                                if (ElementsType === 'label') style.text = tableName
                                else if (ElementsType === 'div') {
                                    const { elementType, styleName } = Elements
                                    const { type } = ElementStyleData[elementType]
                                    Layer.setOptions({ name: tableName, style: type(tableName)[styleName].style })
                                } else style.label.text = tableName
                                Layer.setOptions({ style })
                            }
                            if (textState) {
                                if (Number(textState)) {
                                    if (ElementsType === 'label') style.text = form.getFieldValue('tableName')
                                    else style.label.text = form.getFieldValue('tableName')
                                } else {
                                    if (ElementsType === 'label') {
                                        style.text = ''
                                    } else style.label.text = ''
                                }
                                Layer.setOptions({ style })
                            }
                            if (altitude) {
                                Layer.setOptions({ setHeight: altitude })
                            }

                            if (heading) Layer.heading = heading
                            if (scale) Layer.scale = scale
                            if (closure) {
                                style.closure = Number(closure) ? true : false
                                Layer.setOptions({ style })
                            }
                            if (radius) {
                                style.radius = Number(radius)
                                Layer.setOptions({ style })
                            }
                            if (dimensions) {
                                style.diffHeight = Number(dimensions)
                                Layer.setOptions({ style })
                            }
                            if (speed) {
                                if (style.material._speed) style.material._speed = Number(speed)
                                Layer.setOptions({ style })
                            }
                            if (rotate) {
                                style.rotationDegree = Number(rotate)
                                style.startAngle = Number(rotate)
                                Layer.setOptions({ style })
                            }
                            if (slices) {
                                style.border = Number(slices)
                                Layer.setOptions({ style })
                            }
                            if (semiMinorAxis) {
                                style.semiMinorAxis = Number(semiMinorAxis)
                                Layer.setOptions({ style })
                            }
                            if (semiMajorAxis) {
                                style.semiMinorAxis = Number(semiMajorAxis)
                                Layer.setOptions({ style })
                            }
                            if (topRadius) {
                                style.topRadius = topRadius
                                Layer.setOptions({ style })
                            }
                            if (bottomRadius) {
                                style.bottomRadius = bottomRadius
                                Layer.setOptions({ style })
                            }
                            if (length) {
                                style.length = length
                                Layer.setOptions({ style })
                            }
                        }}
                    >
                        <FormItemModal
                            Map={Map}
                            form={form}
                            data={FormData}
                            ModelUrlEvent={ModelUrlEvent}
                            ColorEvent={ColorEvent}
                        />
                    </Form>
                    <div className="options">
                        <Button block type="primary" onClick={() => form.submit()}>
                            保存数据
                        </Button>
                    </div>
                </>
            ) : (
                <div className="DrawLoading">请先绘制</div>
            )}
        </div>
    )
}

export const ModifyElement = ({ Map, Gra, Elements, ElementDetails, ElementDetailsEvent }) => {
    const [form] = Form.useForm()
    const [FormData, setFormData] = useState([])
    const [ElementStyle, setElementStyle] = useState({})
    const [ElementsType, setElementsType] = useState('')
    const [Layer] = useState(Gra.graphics.find(v => v.id === ElementDetails.uuid))

    // 节流change数据
    const { runAsync: setColorWait } = useRequest(async data => new Promise(resolve => resolve(data)), {
        throttleWait: 1000,
        manual: true,
    })

    useEffect(() => {
        // 阻断执行函数
        if (JSON.stringify(ElementDetails) === '{}') return
        // 跳过阻断后执行的修改参数
        const { elementType, styleName } = Elements
        const { formData, type } = ElementStyleData[elementType]

        setElementsType(elementType)
        setElementStyle(type()[styleName].style)

        const ModifyFormData = JSON.parse(JSON.stringify(formData))

        if (
            (elementType === 'rectangle' && type()[styleName].style.clampToGround === true) ||
            (elementType === 'polygon' && type()[styleName].style.clampToGround === true) ||
            (elementType === 'regular' && type()[styleName].style.clampToGround === true) ||
            (elementType === 'circle' && type()[styleName].style.clampToGround === true) ||
            (elementType === 'ellipse' && type()[styleName].style.clampToGround === true) ||
            (elementType === 'sector' && type()[styleName].style.clampToGround === true)
        ) {
            if (ModifyFormData.findIndex(v => v.name === 'dimensions') !== -1)
                ModifyFormData.splice(
                    ModifyFormData.findIndex(v => v.name === 'dimensions'),
                    1,
                )
        }

        if (elementType === 'ellipse') {
            const { radius } = ElementDetails
            form.setFieldsValue({ semiMinorAxis: radius.split(',')[0], semiMajorAxis: radius.split(',')[1] })
        }
        if (elementType === 'sector') {
            const { angle } = ElementDetails
            form.setFieldsValue({ startAngle: angle[0], endAngle: angle[1] })
        }

        if (elementType === 'cylinder') {
            const { radius } = ElementDetails
            form.setFieldsValue({ topRadius: radius[0], bottomRadius: radius[1], length: radius[2] })
        }

        form.setFieldsValue(ElementDetails)
        Gra.startEditing(Layer)

        Layer.on('click', () => {})

        Layer.on(
            [
                mars3d.EventType.editStart,
                mars3d.EventType.editMovePoint,
                mars3d.EventType.editStyle,
                mars3d.EventType.editRemovePoint,
            ],
            ({ graphic }) => {
                let modifyData = {}
                const { coordinates, heading, scale, style, coordinate } = graphic
                const {
                    rotationDegree,
                    diffHeight,
                    radius,
                    startAngle,
                    endAngle,
                    semiMinorAxis,
                    semiMajorAxis,
                    topRadius,
                    bottomRadius,
                    length,
                } = style
                if (
                    elementType === 'label' ||
                    elementType === 'point' ||
                    elementType === 'billboard' ||
                    elementType === 'model'
                ) {
                    modifyData.position = coordinates[0]
                } else if (elementType === 'div') {
                    modifyData.position = coordinate
                } else {
                    modifyData.position = coordinates
                }
                if (elementType === 'model') {
                    modifyData.heading = heading
                    modifyData.scale = scale
                }

                if (elementType === 'wall' || elementType === 'rectangle' || elementType === 'regular') {
                    modifyData.rotate = rotationDegree
                    modifyData.dimensions = diffHeight
                }
                if (elementType === 'regular' || elementType === 'circle') {
                    modifyData.radius = radius
                    modifyData.rotate = startAngle
                }
                if (elementType === 'ellipse') {
                    modifyData.semiMinorAxis = semiMinorAxis
                    modifyData.semiMajorAxis = semiMajorAxis
                }

                if (elementType === 'sector') {
                    modifyData.dimensions = diffHeight
                    modifyData.radius = radius
                    modifyData.startAngle = startAngle
                    modifyData.endAngle = endAngle
                }
                if (elementType === 'cylinder') {
                    modifyData.topRadius = topRadius
                    modifyData.bottomRadius = bottomRadius
                    modifyData.length = length
                }
                form.setFieldsValue(modifyData)
            },
        )

        setFormData(ModifyFormData)
    }, [ElementDetails, Elements, Gra, Layer, form])

    const ModelUrlEvent = useEventEmitter()
    ModelUrlEvent.useSubscription(val => {
        let style = ElementStyle
        style.url = val
        Layer.setOptions({ position: form.getFieldValue('position'), style })
    })

    const ColorEvent = useEventEmitter()
    ColorEvent.useSubscription(val => {
        setColorWait(val).then(res => {
            let { style } = Layer
            if (ElementsType === 'label') style.color = val
            else if (ElementsType === 'div') {
                let { className } = style
                let tableName = form.getFieldValue('tableName')
                let sortId = form.getFieldValue('sortId')
                style.html = divList(tableName, res, sortId)[className].style.html
            } else {
                style.color = val
                style.label.color = val
            }
            Layer.setOptions({ style })
        })
    })

    // 关闭修改
    useEffect(() => {
        return () => {
            if (JSON.stringify(Gra) !== '{}') Gra.hasEdit = false
        }
    }, [Gra])

    return (
        <div>
            <Form
                className="scenesBase"
                form={form}
                layout="vertical"
                onFinish={e => {
                    e.center = JSON.stringify(e.center)
                    e.position = JSON.stringify(e.position)
                    if (e.semiMinorAxis && e.semiMajorAxis) {
                        e.radius = `${e.semiMinorAxis},${e.semiMajorAxis}`
                        delete e.semiMinorAxis
                        delete e.semiMajorAxis
                    }
                    if (e.startAngle && e.endAngle) {
                        e.angle = JSON.stringify([e.startAngle, e.endAngle])
                        delete e.startAngle
                        delete e.endAngle
                    }
                    if (e.topRadius && e.bottomRadius && e.length) {
                        e.radius = JSON.stringify([e.topRadius, e.bottomRadius, e.length])
                        delete e.topRadius
                        delete e.bottomRadius
                        delete e.length
                    }
                    const data = { ...e, elementsUuid: Elements.elementUuid }
                    ElementDetailsEvent.emit({ type: 'modify', data: data })
                }}
                onValuesChange={({
                    tableName,
                    heading,
                    scale,
                    textState,
                    closure,
                    radius,
                    dimensions,
                    speed,
                    rotate,
                    slices,
                    semiMinorAxis,
                    semiMajorAxis,
                }) => {
                    // let name = ElementStyle
                    let style = Layer.style
                    if (tableName) {
                        if (ElementsType === 'label') style.text = tableName
                        else if (ElementsType === 'div') {
                            const { elementType, styleName } = Elements
                            const { type } = ElementStyleData[elementType]
                            Layer.setOptions({ name: tableName, style: type(tableName)[styleName].style })
                        } else style.label.text = tableName
                        Layer.setOptions({ style })
                    }
                    if (textState) {
                        if (Number(textState)) {
                            if (ElementsType === 'label') style.text = form.getFieldValue('tableName')
                            else style.label.text = form.getFieldValue('tableName')
                        } else {
                            if (ElementsType === 'label') {
                                style.text = ''
                            } else style.label.text = ''
                        }
                        Layer.setOptions({ style })
                    }
                    if (heading) Layer.heading = heading
                    if (scale) Layer.scale = scale
                    if (closure) {
                        style.closure = Number(closure) ? true : false
                        Layer.setOptions({ style })
                    }
                    if (radius) {
                        style.radius = Number(radius)
                        Layer.setOptions({ style })
                    }
                    if (dimensions) {
                        style.diffHeight = Number(dimensions)
                        Layer.setOptions({ style })
                    }
                    if (speed) {
                        if (style.material._speed) style.material._speed = Number(speed)
                        Layer.setOptions({ style })
                    }
                    if (rotate) {
                        style.startAngle = Number(rotate)
                        style.rotationDegree = Number(rotate)
                        Layer.setOptions({ style })
                    }

                    if (slices) {
                        style.border = Number(slices)
                        Layer.setOptions({ style })
                    }
                    if (semiMinorAxis) {
                        style.semiMinorAxis = Number(semiMinorAxis)
                        Layer.setOptions({ style })
                    }
                    if (semiMajorAxis) {
                        style.semiMinorAxis = Number(semiMajorAxis)
                        Layer.setOptions({ style })
                    }
                }}
            >
                <FormItemModal
                    Map={Map}
                    form={form}
                    data={FormData}
                    ModelUrlEvent={ModelUrlEvent}
                    ColorEvent={ColorEvent}
                />
            </Form>
            <div className="options">
                <Button block type="primary" onClick={() => form.submit()}>
                    保存数据
                </Button>
            </div>
        </div>
    )
}
